using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace Poka_Yoke.Analysis
{
    public class Analyser
    {
        private Configuration _config;

        public Analyser(Configuration config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            _config = config;
        }
        
        public List<AnalysisResult> AnalyseFile(string fileName)
        {
            if (String.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            string fileContents = FileHelper.LoadFile(fileName);

            if (fileContents.Length == 0)
            {
                return new List<AnalysisResult>();
            }

            List<AnalysisResult> result = AnalyseString(fileContents);

            return result;
        }

        public List<AnalysisResult> AnalyseDirectory(string directoryName)
        {
            if (String.IsNullOrEmpty(directoryName))
            {
                throw new ArgumentNullException("directoryName");
            }

            if (!Directory.Exists(directoryName))
            {
                throw new DirectoryNotFoundException(directoryName);
            }

            List<AnalysisResult> result = new List<AnalysisResult>();

            DirectoryInfo analyserDirectory = new DirectoryInfo(directoryName);

            foreach(FileInfo file in analyserDirectory.GetFiles(_config.SearchPattern))
            {
                result.AddRange(AnalyseFile(file.FullName));
            }

            foreach(DirectoryInfo directory in analyserDirectory.GetDirectories())
            {
                result.AddRange(AnalyseDirectory(directory.FullName));
            }

            return result;
        }

        public List<AnalysisResult> AnalyseString(string inputString)
        {
            if (String.IsNullOrEmpty(inputString))
            {
                throw new ArgumentNullException("inputString");
            }

            List<AnalysisResult> result = new List<AnalysisResult>();

            foreach(Rule currentRule in _config.RulesCollection)
            {
                MatchCollection matches = currentRule.Pattern.Matches(inputString);

                foreach(Match currentMatch in matches)
                {
                    int lineNumber = FileHelper.CalculateLineNumber(currentMatch.Index, inputString);
                    AnalysisResult ruleResult = new AnalysisResult(lineNumber, currentRule.Message, currentRule.RuleSeverity);

                    result.Add(ruleResult);
                }
            }
            
            return result;
        }
    }
}
